// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// WorldBuilderDoc.cpp : implementation of the CWorldBuilderDoc class
//

#include "stdafx.h"
#include "WorldBuilder.h"
#include "WorldBuilderDoc.h"
#include "MainFrm.h"
#include "MarkerNode.h"
#include "MainView.h"
#include <fstream>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CWorldBuilderDoc

IMPLEMENT_DYNCREATE(CWorldBuilderDoc, CDocument)

BEGIN_MESSAGE_MAP(CWorldBuilderDoc, CDocument)
END_MESSAGE_MAP()


// CWorldBuilderDoc construction/destruction

CWorldBuilderDoc::CWorldBuilderDoc()
{
}

CWorldBuilderDoc::~CWorldBuilderDoc()
{
}

BOOL CWorldBuilderDoc::OnNewDocument()
{
    // Calls the DeleteContents member function to ensure that the document 
    // is empty and then marks the new document as clean. 
    if (!CDocument::OnNewDocument())
        return FALSE;

    theApp.getWorld().getNodeManager().createDummyScene();

    return TRUE;
}



// CWorldBuilderDoc serialization



// Normally MFC serialization uses binary files, but text files 
// are preferrable for a number of reasons (see 
// http://www.codeguru.com/cpp/data/data-misc/xml/article.php/c4567)
// But we want to make use of the standard MFC serialization mechanism
// as it frees us from having to implement all the Open/Save/Save logic
// Therefore, we use the standard CDocument::Serialize override, but
// store our data in text format as opposed to binary. Two things must
// taken into account: (1) use CArchive::WriteString and 
// CArchive::ReadString only and (2) write new lines as "\r\n", as 
// Windows won't do the translation for us
// For additional information see
// See http://www.codeguru.com/forum/archive/index.php/t-402596.html
// TODO what happens in Unix with the fact that we write "\r\n" ??

void CWorldBuilderDoc::Serialize(CArchive& ar)
{
    // Get file name associated to archive
    CFile* file = ar.GetFile();
    CString fileName = file->GetFileName();

    // Close file because we're gonna open the file ourselves
    file->Close();

    // Write to archive
    if(ar.IsStoring())
    {
        // Open the file and write the scene to it
        std::wofstream os((LPCTSTR)fileName);
        theApp.getWorld().write(os);
        os.close();

        // This is what we would have used if we had actually wanted to write
        // to the CArchive provided by MFC
        // writeTextToArchive(oss.str(), ar);
    }
    // Read from archive
    else
    {
        // This is what we would have used if we had actually wanted to write
        // to the CArchive provided by MFC
        // std::string wholeText = readCompleteTextArchive(ar);
        
        std::wifstream is((LPCTSTR)fileName);
        theApp.getWorld().read(is);
        is.close();
    }
    
    // Dirty hack: open the file again because MFC will try to close it
    // from within the OnSave handler
    file->Open(fileName, CFile::modeReadWrite);
}

// CWorldBuilderDoc diagnostics

#ifdef _DEBUG
void CWorldBuilderDoc::AssertValid() const
{
    CDocument::AssertValid();
}

void CWorldBuilderDoc::Dump(CDumpContext& dc) const
{
    CDocument::Dump(dc);
}
#endif //_DEBUG


// CWorldBuilderDoc commands

void CWorldBuilderDoc::DeleteContents()
{
    // TODO the doc should not know about the views so directly

    theApp.getWorld().clear();

    CDocument::DeleteContents();
}

void CWorldBuilderDoc::nodeChangedImpl(NodeManager * /*sender*/)
{
    SetModifiedFlag(1);
    UpdateAllViews(NULL);
}